package rpcserver

import (
	"fmt"
	"gitee.com/jamon/espoir_go/common"
	"gitee.com/jamon/espoir_go/global"
	"gitee.com/jamon/espoir_go/logger"
	"gitee.com/jamon/espoir_go/route"
	"gitee.com/jamon/espoir_go/service"
)

// 主动消息处理，如push消息，节点间消息等

type InternalHandler struct {
	nodeData   *global.NodeData
	serviceMgr *service.Manager
	routeCtl   *route.Controller
	sessionMgr *global.SessionManager
}

func NewInternalHandler() (handler *InternalHandler, err error) {
	handler = &InternalHandler{
		nodeData:   global.GetNodeData(),
		serviceMgr: service.GetManager(),
		routeCtl:   route.GetController(),
		sessionMgr: global.GetSessionManager(),
	}
	return
}

func (handler *InternalHandler) HandleMsg(req common.InternalNotifyRequest, res *common.MsgResponse) (err error) {
	if req.Type != common.MsgType_INTERNAL_NOTIFY {
		err = fmt.Errorf("unknown msg type: %v", req.Type)
		return
	}
	err = handler.handleInternalNotify(&req, res)
	return
}

func (handler *InternalHandler) handleInternalNotify(req *common.InternalNotifyRequest, res *common.MsgResponse) (err error) {
	// 几种使用场景:
	// 1. service 发送消息往proxy，精确定位；
	// 2. proxy 发送消息往service，精确定位；
	// 3. service发往另一个service, 需要经过proxy中转寻址；

	if req.To == handler.nodeData.Config.NodeID {
		// 如果目的地是当前节点（可为proxy, 或service）, 本地处理
		err = handler.serviceMgr.HandleInternalNotify(req, res)
		return
	}

	if handler.nodeData.GetCurNodeType() == common.NodeType_Proxy {
		// proxy 节点, 则转发消息往service
		err = handler.routeCtl.RemoteInternalHandle(req, res)
		return
	}

	err = fmt.Errorf("invalid notify request: %v", req)
	logger.Error("handleInternalNotify: ", logger.Kwargs{"err": err, "req": req})
	return
}
